﻿//Szu
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

using Global;

//15 kwietnia 2011 - dzień, w którym Strzała nie zjawił się na wykładzie
namespace CharacterLibrary
{
    /// <summary>
    /// Tytułowy Pacman
    /// </summary>
    class Pacman:Character
    {
        private static string PATH = @"CINEMA4D/pacman";
        private TimeSpan indTime = TimeSpan.Zero; 
        private bool indestructible;
        public bool Indestructible
        { 
            get
            {
                return indestructible;
            }
            set
            {
                indestructible = value;
            }
        }
        private bool canMove;
        private int points;
        public int Points
        {
            get
            {
                return points;
            }
            set
            {
                if (value >= 0) points = value;
            }
        }

        private int lives;
        /// <summary>
        /// Zmniejsza liczę żyć pacmana i sprawdza, czy ma wystarczająco dużo życdo dalszej 
        /// </summary>
        /// <returns>czy możliwa jest kontynuacja gry</returns>
        public bool living()
        {
            return lives-- > 1 ? true : false;
        }

        public int Lives
        {
            get
            {
                return lives;
            }
            set
            {
                if(value>=0)
                    lives=value;
                else
                    lives=0;
            }
        }
        /// <summary>
        /// Sprawdzenie, czy w danym okresie Pacman jest niezniszczalny.
        /// </summary>
        /// <param name="gameTime">Aktualny czas rozgrywki.</param>
        /// <returns>czy Pacman jest niezniszczalny</returns>
        public bool isIndestructible(GameTime gameTime)
        {

            if (indTime > gameTime.TotalGameTime)
            {
                indestructible = true;
                speed = GameSettings.pacmanSpeed * 1.5f;
                Score.indestructibleTimeLeft = indTime - gameTime.TotalGameTime;
                return indestructible;
            }
            else
            {
                indestructible = false;
                speed = GameSettings.pacmanSpeed;
                Score.indestructibleTimeLeft = TimeSpan.Zero;
                return indestructible;
            }

        }
        public TimeSpan getIndTimeLeft(GameTime gameTime)
        {
            return indTime;
        }
        /// <summary>
        /// Jeżeli nastąpi kolizja z wybraną kulką, jaki ma ona wpływ na Pacmana.
        /// </summary>
        /// <param name="ball">kulka z którą Pacman się zderza</param>
        /// <param name="gameTime">Aktualny czas gry.</param>
        public void ballCollision(Ball ball, GameTime gameTime)
        {
            switch (ball.size)
            {
                case Ball.BallSize.Small:
                    points += Global.GameSettings.pointsPerSmallBall;
                    Sound.eatCoin.Play();
                    break;
                default: //BallSize.Big
                    indTime = TimeSpan.FromMilliseconds(Global.GameSettings.pacmanIndestructibleTime) + gameTime.TotalGameTime;
                    Score.indestructibleTimeLeft = indTime;
                    points += Global.GameSettings.pointsPerBigBall;
                    Sound.eatBall.Play();
                    break;
                    
            }
        }
        /// <summary>
        /// Sprawdzenie, czy możliwe jest poruszanie się Packamana w danym kierunku.
        /// </summary>
        /// <param name="rows">Współrzędne X</param>
        /// <param name="cols">Współrzędne Y</param>
        /// <param name="reservedPlace">Tablica z zajętymi polami.</param>
        public void checkMove(int rows, int cols, bool[,] reservedPlace)
        {
            if (((position.X >= rows - 1) && (base.direction == DirectionType.right)) ||
                ((position.X <= 0) && (base.direction == DirectionType.left)) ||
                ((position.Z >= cols - 1) && (base.direction == DirectionType.down)) ||
                ((position.Z <= 0) && (base.direction == DirectionType.up)))
            {
                canMove = false;
                return;
            }
            //Tego ifa czytać jako "jeżeli idziemy w danym kierunku i jedno z pól do którego zmierzamy (+0.5) jest zajęte, to wzróć false, że się nie da".
            if ((((reservedPlace[(int)Math.Round(Pos.X + 0.5), (int)Math.Round(Pos.Z - Global.ConstantVision.WallDetection)]) || reservedPlace[(int)Math.Round(Pos.X + 0.5), (int)Math.Round(Pos.Z + Global.ConstantVision.WallDetection)]) && base.direction.Equals(DirectionType.right)) ||
                (((reservedPlace[(int)Math.Round(Pos.X - 0.5), (int)Math.Round(Pos.Z - Global.ConstantVision.WallDetection)]) || reservedPlace[(int)Math.Round(Pos.X - 0.5), (int)Math.Round(Pos.Z + Global.ConstantVision.WallDetection)]) && base.direction.Equals(DirectionType.left)) ||
                (((reservedPlace[(int)Math.Round(Pos.X - Global.ConstantVision.WallDetection), (int)Math.Round(Pos.Z + 0.5)]) || reservedPlace[(int)Math.Round(Pos.X + Global.ConstantVision.WallDetection), (int)Math.Round(Pos.Z + 0.5)]) && base.direction.Equals(DirectionType.down)) ||
                (((reservedPlace[(int)Math.Round(Pos.X - Global.ConstantVision.WallDetection), (int)Math.Round(Pos.Z - 0.5)]) || reservedPlace[(int)Math.Round(Pos.X + Global.ConstantVision.WallDetection), (int)Math.Round(Pos.Z - 0.5)]) && base.direction.Equals(DirectionType.up)))
            {
                canMove = false;
                return;
            }
            canMove = true;
            
        }
        public Pacman(int lives, ContentManager content, GraphicsDeviceManager graphics, int xPoz, int zPos, float speed):base(graphics, xPoz, zPos)
        {
            this.speed = speed; 
            this.lives = lives;
            Vector3 position = new Vector3(xPoz, Global.ConstantVision.InitYObjectPosition, zPos);
            model = content.Load<Model>(PATH);
            this.position = position;
            bornPlace = position;
            indestructible = false;
        }
        /// <summary>
        /// Poruszanie się Pacmana.
        /// </summary>
        public override void Move()
        {
            if (canMove)
                base.Move();
        }
        /// <summary>
        /// Rysowanie pacmana
        /// </summary>
        public override void Draw()
        {

            foreach (ModelMesh mesh in model.Meshes)
            {
              
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = Matrix.CreateRotationY(((float)Math.PI) * (int)direction / 2 + (float)(Math.PI)) * Matrix.CreateTranslation(position);
                    /*
                    switch(direction)
                    {
                      case DirectionType.down: objectDirection = 
                    }
                    objectDirection = direction
                    */
                    effect.World = Matrix.CreateRotationY(((float)Math.PI) * (int)direction/*(int)direction*/ / 2 + (float)(Math.PI)) * Matrix.CreateTranslation(position);
                    effect.View = Global.Vision.view;
                    effect.Projection = Global.Vision.projection;
                    effect.EnableDefaultLighting();
                    if (indestructible) // jeśli pacman jest teraz niezniszczalny to zmień jego kolor na czerwony
                    {
                        effect.DiffuseColor = new Vector3(1, 0.1f, 0);
                    }
                    else // zwykły pacman - kolor żółty
                    {
                        effect.DiffuseColor = new Vector3(0.8f, 0.7f, 0);
                    }                             
                }
                mesh.Draw();
            }
        }
        
    }
}
